<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Simplified Hibernate ORM with Panache and Kotlin</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/hibernate-orm-panache-kotlin" />
  <meta property="og:title" content="Quarkus - Simplified Hibernate ORM with Panache and Kotlin" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/hibernate-orm-panache-kotlin">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Simplified Hibernate ORM with Panache and Kotlin</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#first-an-example">First: an example</a></li>
<li><a href="#using-the-repository-pattern">Using the repository pattern</a>
<ul class="sectlevel2">
<li><a href="#defining-your-entity">Defining your entity</a></li>
<li><a href="#defining-your-repository">Defining your repository</a></li>
<li><a href="#most-useful-operations">Most useful operations</a></li>
</ul>
</li>
<li><a href="#setting-up-and-configuring-hibernate-orm-with-panache">Setting up and configuring Hibernate ORM with Panache</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Hibernate ORM is the de facto standard JPA implementation and is well-known in the Java ecosystem.  Panache offers a
new layer atop this familiar framework.  This guide will not dive in to the specifics of either as those are already
covered in the <a href="hibernate-orm-panache.adoc">Panache guide</a>.  In this guide, we&#8217;ll cover the Kotlin specific changes
needed to use Panache in your Kotlin-based Quarkus applications.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="first-an-example"><a class="anchor" href="#first-an-example"></a>First: an example</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As we saw in the Panache guide, Panache allows us to extend the functionality in our entities and repositories (also known as DAOs) with some automatically
provided functionality.  When using Kotlin, the approach is very similar to what we see in the Java version with a slight
change or two.  To Panache-enable your entity, you would define it something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">@Entity
class Person: PanacheEntity {
    lateinit var name: String
    lateinit var birth: LocalDate
    lateinit var status: Status
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As you can see our entities remain simple.  There is, however, a slight difference from the Java version.  The Kotlin
language doesn&#8217;t support the notion of static methods in quite the same way as Java does.  Instead, we must use a
[companion object](<a href="https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#companion-objects" class="bare">https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#companion-objects</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">@Entity
class Person : PanacheEntity {
    companion object: PanacheCompanion&lt;Person&gt; {  <i class="conum" data-value="1"></i><b>(1)</b>
        fun findByName(name: String) = find("name", name).firstResult()
        fun findAlive() = list("status", Status.Alive)
        fun deleteStefs() = delete("name", "Stef")
    }

    lateinit var name: String  <i class="conum" data-value="2"></i><b>(2)</b>
    lateinit var birth: LocalDate
    lateinit var status: Status
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The companion object holds all the methods not related to a specific instance allowing for general management and
querying bound to a specific type.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Here there are options, but we&#8217;ve chosen the <code>lateinit</code> approach.  This allows us to declare these fields as non-null
knowing they will be properly assigned either by the constructor (not shown) or by hibernate loading data from the
database.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
These types differ from the Java types mentioned in those tutorials.  For Kotlin support, all the Panache
types will be found in the <code>io.quarkus.hibernate.orm.panache.kotlin</code> package.  This subpackage allows for the distinction
between the Java and Kotlin variants and allows for both to be used unambiguously in a single project.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In the Kotlin version, we&#8217;ve simply moved the bulk of the <a href="https://www.martinfowler.com/eaaCatalog/activeRecord.html"><code>active record pattern</code></a>
functionality to the <code>companion object</code>.  Apart from this slight change, we can then work with our types in ways that map easily
from the Java side of world.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-the-repository-pattern"><a class="anchor" href="#using-the-repository-pattern"></a>Using the repository pattern</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="defining-your-entity"><a class="anchor" href="#defining-your-entity"></a>Defining your entity</h3>
<div class="paragraph">
<p>When using the repository pattern, you can define your entities as regular JPA entities.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">@Entity
class Person {
    @Id
    @GeneratedValue
    var id: Long? = null;
    lateinit var name: String
    lateinit var birth: LocalDate
    lateinit var status: Status
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="defining-your-repository"><a class="anchor" href="#defining-your-repository"></a>Defining your repository</h3>
<div class="paragraph">
<p>When using Repositories, you get the exact same convenient methods as with the active record pattern, injected in your Repository,
by making them implement <code>PanacheRepository</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">class PersonRepository: PanacheRepository&lt;Person&gt; {
     fun findByName(name: String) = find("name", name).firstResult()
     fun findAlive() = list("status", Status.Alive)
     fun deleteStefs() = delete("name", "Stef")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>All the operations that are defined on <code>PanacheEntityBase</code> are available on your repository, so using it
is exactly the same as using the active record pattern, except you need to inject it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">@Inject
lateinit var personRepository: PersonRepository

@GET
fun count() = personRepository.count()</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="most-useful-operations"><a class="anchor" href="#most-useful-operations"></a>Most useful operations</h3>
<div class="paragraph">
<p>Once you have written your repository, here are the most common operations you will be able to perform:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">// creating a person
var person = Person()
person.name = "Stef"
person.birth = LocalDate.of(1910, Month.FEBRUARY, 1)
person.status = Status.Alive

// persist it
personRepository.persist(person)

// note that once persisted, you don't need to explicitly save your entity: all
// modifications are automatically persisted on transaction commit.

// check if it's persistent
if(personRepository.isPersistent(person)){
    // delete it
    personRepository.delete(person)
}

// getting a list of all Person entities
val allPersons = personRepository.listAll()

// finding a specific person by ID
person = personRepository.findById(personId) ?: throw Exception("No person with that ID")

// finding all living persons
val livingPersons = personRepository.list("status", Status.Alive)

// counting all persons
val countAll = personRepository.count()

// counting all living persons
val countAlive = personRepository.count("status", Status.Alive)

// delete all living persons
personRepository.delete("status", Status.Alive)

// delete all persons
personRepository.deleteAll()

// delete by id
val deleted = personRepository.deleteById(personId)

// set the name of all living persons to 'Mortal'
personRepository.update("name = 'Mortal' where status = ?1", Status.Alive)</code></pre>
</div>
</div>
<div class="paragraph">
<p>All <code>list</code> methods have equivalent <code>stream</code> versions.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="kotlin" class="language-kotlin hljs">val persons = personRepository.streamAll();
val namesButEmmanuels = persons
    .map { it.name.toLowerCase() }
    .filter { it != "emmanuel" }</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>stream</code> methods require a transaction to work.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The rest of the documentation show usages based on the active record pattern only,
but keep in mind that they can be performed with the repository pattern as well.
The repository pattern examples have been omitted for brevity.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>For more examples, please consult the <a href="hibernate-orm-panache">Java version</a> for complete details.  Both APIs
are the same and work identically except for some Kotlin-specific tweaks to make things feel more natural to
Kotlin developers.  These tweaks include things like better use of nullability and the lack of <code>Optional</code> on API
methods.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-up-and-configuring-hibernate-orm-with-panache"><a class="anchor" href="#setting-up-and-configuring-hibernate-orm-with-panache"></a>Setting up and configuring Hibernate ORM with Panache</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To get started using Panache with Kotlin, you can, generally, follow the steps laid out in the Java tutorial.  The biggest
change to configuring your project is the Quarkus artifact to include.  You can, of course, keep the Java version if you
need but if all you need are the Kotlin APIs then include the following dependency instead:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependencies&gt;
    &lt;!-- Hibernate ORM specific dependencies --&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
        &lt;artifactId&gt;quarkus-hibernate-orm-panache-kotlin&lt;/artifactId&gt;  <i class="conum" data-value="1"></i><b>(1)</b>
    &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Note the addition of <code>-kotlin</code> on the end.  Generally you&#8217;ll only need this version but if your project will be using
both Java and Kotlin code, you can safely include both artifacts.</td>
</tr>
</table>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
